#!/usr/bin/env python

from gi.repository import Gtk,Gdk


import os
import pprint
import inspect 
import random

class Handler:
    def __init__(self,par):
        self.par=par
        pprint.pprint(par)
    def onQuit(self, *args):
        Gtk.main_quit(*args)
    def on_buttonRescan_clicked (self,*args):
        self.par.rescan()
    def on_buttonParola_clicked (self,*args):
        self.par.parolaForward()
    def on_buttonParolaPrec_clicked(self,*args):
        self.par.parolaBackward()
    def on_radiobuttonPlain_toggled(self,*args):
        self.par.refreshWords()
    def on_radiobuttonRandom_toggled(self,*args):
        self.par.refreshWords()
    def on_radiobuttonAlwaysRandom_toggled(self,*args):
        self.par.refreshWords()
    def on_listboxParole_row_selected(self,*args):
        print("ROW SELECTED: ")
        pprint.pprint(args)
    def on_listboxParole_row_activated(self,*args):
#        print("ROW ACTIVATED: ")
#        pprint.pprint(args)
        self.par.parolaSelected(args[1])
    def on_windowApp_key_release_event(self,widget,ev,data=None):
        print("KEY RELEASED ACTIVATED: ")
        keyname = Gdk.keyval_name(ev.keyval)
        print( "keyname: " + keyname)
        if keyname == "Q" or keyname == 'q':
            self.onQuit()
        elif keyname == 'BackSpace':
            self.on_buttonParolaPrec_clicked()
#        if ev.keyval == Gdk.KEY_Escape: #If Escape pressed, reset text
#            print("ESC\n")
            
        
        


class Par:
    datadir = os.path.join(os.path.expanduser("~"),"Parole")
    def __init__(self):
        self.builder = Gtk.Builder()
        self.builder.add_from_file("ui.glade")
        self.builder.connect_signals(Handler(self))
        self.windowApp = self.builder.get_object("windowApp")
        self.windowParola = self.builder.get_object("windowParola")
        self.listboxParole = self.builder.get_object("listboxParole")
        self.listboxGruppi = self.builder.get_object("listboxGruppi")
        self.radiobuttonSelectAll = self.builder.get_object("radiobuttonSelectAll")
        self.radiobuttonSelectNone = self.builder.get_object("radiobuttonSelectNone")     
        self.radiobuttonRandom = self.builder.get_object("radiobuttonRandom")
        self.radiobuttonPlain  = self.builder.get_object("radiobuttonPlain")
        self.radiobuttonAlwaysRandom  = self.builder.get_object("radiobuttonAlwaysRandom")
        self.buttonParola = self.builder.get_object("buttonParola")
        self.labelWord = self.builder.get_object("labelWord")
        self.count=0
        self.parole_rows = []
        self.gruppi_rows = []

        self.parole_fifo_i = -1
        self.parole_fifo_idx = []

        self.parole_row2idx = dict()
        self.gruppi_buttons = []

        self.rescan()
#        for obj in self. builder.get_objects():
#            print obj
        self.windowApp.show_all()
        self.windowParola.show_all()
        
    def rescan(self):
        self.words = dict();
        os.chdir(self.datadir)

        pprint.pprint(self.listboxGruppi)
        # remove all widget from gruppi:
        for row in self.gruppi_rows:
            self.listboxGruppi.remove(row)
        self.gruppi_rows = []
        self.gruppi_buttons = []

        for file in os.listdir(self.datadir):
            if file.endswith(".txt"):
                self.addScanEntry(file.strip(".txt") , file)

# following line is due a bug, see :
# http://stackoverflow.com/questions/24951165/how-can-i-update-gtk-listbox-dynamically/28480871#28480871
        self.listboxGruppi.show_all()
        self.windowParola.maximize()
        self.refreshWords()
              
    def addScanEntry(self,name,file):
         row = Gtk.ListBoxRow()
         self.count+=1
#         label = Gtk.Label(name , xalign=0)
         cbutton=Gtk.CheckButton(name)
         cbutton.connect("clicked",self.onClickedGroup)
         flag1=self.radiobuttonSelectAll.get_active() 
         flag2=self.radiobuttonSelectNone.get_active() 
         pprint.pprint(flag1)
#        pprint.pprint(flag2)
         box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
         cbutton.set_active(flag1)
         box.pack_start(cbutton, True, True, 0)
         row.add(box)
         self.listboxGruppi.add(row)
         self.gruppi_rows.append(row)
         self.gruppi_buttons.append(cbutton)
         self.words[cbutton] = [line.strip() for line in open(file)]         
#         pprint.pprint(vars(row))

    def onClickedGroup(self,widget):
        self.refreshWords()



    def showCurrentWord(self,select_row_flag,backword_mode=False):
#        if(backword_mode):
#           self.labelWord.modify_bg(Gtk.STATE_NORMAL, Gdk.color_parse("blue"))
        if(len(self.finalWordList) == 0 ):
            self.labelWord.set_label("?")
            return
        cur_w=self.parole_fifo_idx[self.parole_fifo_i]
        self.labelWord.set_label(self.finalWordList[cur_w])
        if(select_row_flag):
            self.listboxParole.select_row(self.parole_rows[cur_w])
            self.listboxParole.show_all()

    def parolaSelected(self,row):
        if(row in self.parole_row2idx):
            self.parole_fifo_i = self.parole_row2idx[row]
            self.showCurrentWord(False)
        else:
            pprint.pprint(row)
            print("is not in row2idx")

    def generateNextWord(self):
        self.dump("generateNextWord")
        cur_w=0
        if self.parole_fifo_i >= 0:
            cur_w=self.parole_fifo_idx[self.parole_fifo_i]
        if(len(self.finalWordList) == 0):
            self.showCurrentWord(False)
            return
        if(self.radiobuttonRandom.get_active() or
           self.radiobuttonPlain.get_active() ):
            cur_w +=1
            if(cur_w >= len(self.finalWordList) ):
                cur_w=0
        if(self.radiobuttonAlwaysRandom.get_active()):
            precWordIndex = cur_w
            while(precWordIndex == cur_w):
                cur_w = random.randint(0,len(self.finalWordList)-1)
        self.parole_fifo_idx.append(cur_w)
        self.parole_fifo_i = len(self.parole_fifo_idx)-1
        if len(self.parole_fifo_idx) > len(self.finalWordList):
            self.parole_fifo_idx.pop(0)
        self.showCurrentWord(True)



    def parolaForward(self):
        if self.parole_fifo_i < 0 or self.parole_fifo_i == len(self.parole_fifo_idx) -1 :
            self.dump("parolaForward 1 -->")
            self.generateNextWord()
        else:
            self.dump("parolaForward 2 -->")
            self.parole_fifo_i += 1
            self.showCurrentWord(True)
        self.dump("--> parolaForward")

    def dump(self,msg=""):
        cur_w=-1
        if self.parole_fifo_i>=0:
            cur_w=self.parole_fifo_idx[self.parole_fifo_i]
        cur_s=""
        if cur_w>=0 and cur_w < len(self.finalWordList) :
            cur_s= self.finalWordList[cur_w]
        print ("%s: i=%d cur_w=%d str=%s" %  ( msg, 
                                          self.parole_fifo_i,
                                          cur_w,
                                          cur_s))               
        pprint.pprint(self.parole_fifo_idx)
        print ("\n")

    def parolaBackward(self):
        if self.parole_fifo_i > 0:
            self.dump("parolaBackward 2 -->")
            self.parole_fifo_i -= 1
            self.showCurrentWord(True,True)
        self.dump("--> parolaBackward");
        

    def refreshWords(self):

         # 1. generate words, set finalWordList
        self.finalWordList = []
        self.parole_fifo_i = -1
        self.parole_fifo_idx = []

        for cbutton in self.gruppi_buttons:
            if(cbutton.get_active()):
                self.finalWordList.extend(self.words[cbutton])
        # now see what kind of order:
        if(self.radiobuttonRandom.get_active()):
             random.shuffle(self.finalWordList)

        # 2 - build other widget & structures based on finalWordList
        for row in self.parole_rows:
            self.listboxParole.remove(row)
        i=0
        self.parole_row2idx = dict()
        for s in self.finalWordList:
            row = Gtk.ListBoxRow()
            box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
            label = Gtk.Label(s)
            box.pack_start(label, True, True, 0)
            row.add(box)
            self.listboxParole.add(row)    
            self.parole_rows.append(row)
            self.parole_row2idx[row]=i
            i+=1
        self.listboxParole.show_all()
        self.parolaForward()
        self.buttonParola.grab_focus()



par = Par()
Gtk.main()
